#ifndef LAURIN_DISCOVER_DEVICES_H_
#define LAURIN_DISCOVER_DEVICES_H_

#include "laurin-module.h"
#include "laurin-module-handler.h"
#include "laurin-80211-monitor-device.h"
#include "laurin-80211-frame.h"
#include "laurin-80211-flow.h"
#include "network/laurin-80211-network-set.h"
#include "network/laurin-80211-station.h"
#include <glibmm/ustring.h>
#include <list>


void processFrameExtForDevices(u_char* arg, const struct pcap_pkthdr *header,const u_char *data);



/**
 * This class is the module responsible for discover the 802.11 devices nearby the user station.
 *
 * See the LaurinModule for documentation of Laurin's module internal structure.
 *
 * After its work, we can retrieve the result through the getNetworkSet() method. This method return a list of discovered wireless networks
 * and each of these are filled with the discovered access points and stations.
 *
 *
 * Access Points are discovered in passive way: beacon frames are read when arrive.
 * Stations are discovered by reading the data frames.
 *
 * The class can be configured by
 *
 * 1) The capture interval
 * 2) The maximum number of frames that can be captured
 * 3) Enable/ disable location procedure.
 *
 */

class LaurinDiscoverDevicesModule : public LaurinModule
{
	friend void processFrameExtForDevices(u_char* arg, const struct pcap_pkthdr *header,const u_char *data);

	public:

		LaurinDiscoverDevicesModule(const Glib::ustring& ifaceName, const Glib::ustring& masterIfaceName, LaurinModuleHandler* handler);
		virtual ~LaurinDiscoverDevicesModule();

		bool isInitialized() const;


		Laurin80211NetworkSet* getNetworkSet();


		void setLocationEnable(bool enable);
		bool isLocationEnabled() const;

		void setCaptureInterval(int interval);
		int getCaptureInterval() const;

		void setMaxNumberOfCapturedFrame(int max);
		int getMaxNumberOfCapturedFrame() const;


	protected:

		virtual bool run();
		virtual void innerStop();


	private:

		std::list<Laurin80211Frame> _collected_frames;


		Laurin80211NetworkSet* _networks;
		Laurin80211MonitorDevice* _device;
		LaurinModuleHandler* _handler;


		/* Module configurations values */
		int _max_number_of_captured_frame;
		int _capture_interval;
		bool _is_location_enabled;



		/*
		 * If checkAP is true, then the station is checked over the discovered ap. If the station
		 * is an ap, then the station it will be not added.
		 */
		void addStation(Laurin80211Station* station, bool checkAP);
		void addStation(Laurin80211Frame* frame);
		void addAccessPoint(Laurin80211Frame* frame);
		void processFrame(const struct pcap_pkthdr *header,const u_char *data);
		void doLocation();
		int64_t calculateDurations(const Laurin80211Frame& frame);
		Laurin80211Flow* calculateDistance(const Laurin80211Frame& data, const Laurin80211Frame& ack, bool direction);
		void calculateDistanceFromAP();
		void clearResources();

};

#endif
